/* Copyright (C) 1999-2004 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT ANY 
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
   PARTICULAR PURPOSE.  See the GNU General Public License for more details. */

package artofillusion;

import artofillusion.math.*;
import artofillusion.object.*;
import artofillusion.ui.MeshEditController;
import artofillusion.view.*;
import buoy.widget.*;
import java.awt.*;

/** TubeViewer subclasses CurveViewer to display a Tube that is being edited. */

public class TubeViewer extends CurveViewer
{
  public TubeViewer(MeshEditController window, RowContainer p)
  {
    super(window, p);
  }

  protected void drawObject(Graphics g)
  {
    // First draw the surface.
    
    if (showSurface)
      {
        ObjectInfo objInfo = controller.getObject();
        if (renderMode == RENDER_WIREFRAME)
          {
            g.setColor(surfaceColor);
            Object3D.draw(g, theCamera, objInfo.getWireframePreview(), objInfo.getBounds());
          }
        else if (renderMode == RENDER_TRANSPARENT)
          renderMeshTransparent(objInfo.getPreviewMesh(), new ConstantVertexShader(surfaceRGB), theCamera, theCamera.getViewToWorld().timesDirection(Vec3.vz()), null);
        else
        {
          RenderingMesh mesh = objInfo.getPreviewMesh();
          Vec3 viewDir = theCamera.getViewToWorld().timesDirection(Vec3.vz());
          VertexShader shader;
          if (renderMode == RENDER_FLAT)
            shader = new FlatVertexShader(mesh, surfaceRGB, viewDir);
          else if (renderMode == RENDER_SMOOTH)
            shader = new SmoothVertexShader(mesh, surfaceRGB, viewDir);
          else
            shader = new TexturedVertexShader(mesh, objInfo.object, 0.0, viewDir).optimize();
          renderMesh(mesh, shader, theCamera, objInfo.object.isClosed(), null);
        }
      }
    
    // Now draw the central curve.

    if (showMesh)
      {
        MeshVertex v[] = ((Mesh) getController().getObject().object).getVertices();
        Vec2 pos[] = new Vec2 [v.length];
        for (int i = 0; i < v.length; i++)
          pos[i] = theCamera.getObjectToScreen().timesXY(v[i].r);
        if (renderMode == RENDER_WIREFRAME)
          {
            g.setColor(Color.black);
            for (int i = 0; i < v.length-1; i++)
              g.drawLine((int) pos[i].x, (int) pos[i].y, (int) pos[i+1].x, (int) pos[i+1].y);
            if (((Tube) getController().getObject().object).getEndsStyle() == Tube.CLOSED_ENDS)
              g.drawLine((int) pos[v.length-1].x, (int) pos[v.length-1].y, (int) pos[0].x, (int) pos[0].y);
          }
        else
          {
            for (int i = 0; i < v.length-1; i++)
              renderLine(v[i].r, v[i+1].r, theCamera, Color.black);
            if (((Tube) getController().getObject().object).getEndsStyle() == Tube.CLOSED_ENDS)
              renderLine(v[v.length-1].r, v[0].r, theCamera, Color.black);
          }
    
        // Draw the handles for the control points.
    
        boolean selected[] = ((TubeEditorWindow) controller).getSelection();
        for (int i = 0; i < v.length; i++)
          if (!selected[i] && theCamera.getObjectToView().timesZ(v[i].r) > theCamera.getClipDistance())
            {
              if (renderMode == RENDER_WIREFRAME)
                g.fillRect(((int) pos[i].x) - HANDLE_SIZE/2, ((int) pos[i].y) - HANDLE_SIZE/2, HANDLE_SIZE, HANDLE_SIZE);
              else
                {
                  double z = theCamera.getObjectToView().timesZ(v[i].r);
                  renderBox(((int) pos[i].x) - HANDLE_SIZE/2, ((int) pos[i].y) - HANDLE_SIZE/2, HANDLE_SIZE, HANDLE_SIZE, z, Color.black);
                }
            }
        Color color = (currentTool.hilightSelection() ? Color.magenta : Color.black);
        if (g != null)
          g.setColor(color);
        for (int i = 0; i < v.length; i++)
          if (selected[i] && theCamera.getObjectToView().timesZ(v[i].r) > theCamera.getClipDistance())
            {
              if (renderMode == RENDER_WIREFRAME)
                g.fillRect(((int) pos[i].x) - HANDLE_SIZE/2, ((int) pos[i].y) - HANDLE_SIZE/2, HANDLE_SIZE, HANDLE_SIZE);
              else
                {
                  double z = theCamera.getObjectToView().timesZ(v[i].r);
                  renderBox(((int) pos[i].x) - HANDLE_SIZE/2, ((int) pos[i].y) - HANDLE_SIZE/2, HANDLE_SIZE, HANDLE_SIZE, z, color);
                }
            }
      }
  }
}
